Code of the statistical analysis for the article ‘Life Beyond A Jar: Effects of Tank Size and Enrichment on the Behaviour and Welfare of Siamese Fighting Fishes’
Author
Juliette Tariel-Adam
Published
April 23, 2024
The script contains the code of data transformation, analysis and graphs for the article “Life Beyond A Jar: Effects of Tank Size and Enrichment on the Behaviour and Welfare of Siamese Fighting Fishes” by XXauthorsXXX. It is in two versions: the raw R script in qmd format and the code output in html format.
The goal was to test the effect of tank enrichment and size on Siamese fish behaviour. The tanks Jar, Small, Medium and Large are compared among each other, and the tank Large and Barren between each other. Barren is not compared to Jar, Small or Medium because they differ by two factors: enrichment and size.
On the html version of the code, you fill find below a first row of tabs to click on (PCA, Swimming, etc) and for most of these tabs, a second row of tabs to click on (Distribution, Plot, etc).
After staying 3-7 days in a tank, the behaviour of all fish were scored by four 10-min trials in their tank. All trials occurred on the same day at 4 different times (7 am, 10 am, 2 pm, 6 pm). During the 10 min trial = 600 sec, the fish’s behaviour was assigned to one of the 10 behaviours, meaning that the behaviours are mutually exclusive (for instance, a fish can’t be scored as nest building and interacting with the surface at the same time): Resting, Swimming, Hovering, Sinking/Floating, Stereotypic swimming, Nest building, Foraging, Interation with surface, Out of view, Unsure. Unsure is not present in the raw dataset. Out.of.view is a bit special because it is not a behaviour and was not analysed. Sinking/Floating was not analysed (see explanation in the PCA section).
The data has been inspected and corrected for data entry errors (sum of scored behaviours too low/high, column shifted, typos, inconsistent nb of observations per fish/time/tank…).
Each row represents a trial. For each trial, there is: + Fish: the fish tested + Tank: in which tank the fish was + Order: the tank order, i.e. whether it was the first, second, …, fifth tank that the fish experienced. + Time: time of the day at which the trial happened + Filter: where there a filter in the tank + Behavioural columns. The columns for the behaviours are the time spent doing the specific behaviour in seconds during the trial. Some behaviours (Forgaging, Hovering, Interaction.with.Surface, Stereotypic.swimming) have been trasnformed in binary variable (.bin). The columns .bins represents if the fish performed the specific behaviour at all during the trial or not.
summary(data)
Fish Tank Order Time Filter Swimming
Elf : 20 Jar :48 1:52 7:00 AM :63 No-filter:180 Min. : 0.0
Fairy : 20 Small :52 2:52 10:00 AM:63 Filter : 72 1st Qu.:133.9
Ghost : 20 Medium:52 3:48 2:00 PM :63 Median :224.8
Goblin : 20 Large :52 4:52 6:00 PM :63 Mean :224.6
Kinara : 20 Barren:48 5:48 3rd Qu.:309.2
Kraken : 20 Max. :486.8
(Other):132
Resting Hovering Stereotypic.swimming Nest.building
Min. : 0.00 Min. : 0.00 Min. : 0.00 Min. : 0.00
1st Qu.: 92.33 1st Qu.: 6.01 1st Qu.: 0.00 1st Qu.: 0.00
Median :190.99 Median : 23.71 Median : 0.00 Median : 0.00
Mean :226.04 Mean : 42.93 Mean : 42.47 Mean : 33.72
3rd Qu.:354.97 3rd Qu.: 56.21 3rd Qu.: 20.58 3rd Qu.: 0.00
Max. :600.00 Max. :344.27 Max. :549.00 Max. :512.99
Foraging Interation.with.surface Foraging.bin SS.bin Hovering.bin
Min. : 0.00 Min. : 0.000 No :168 No :172 No : 48
1st Qu.: 0.00 1st Qu.: 0.000 Yes: 84 Yes: 80 Yes:204
Median : 0.00 Median : 1.545
Mean : 7.83 Mean : 15.331
3rd Qu.: 7.80 3rd Qu.: 14.117
Max. :125.28 Max. :251.000
Interacting.bin Nest.bin
No :125 No :201
Yes:127 Yes: 51
# Number of observations per fish per tankdata %>%group_by(Fish, Tank) %>%summarise(n=n(), .groups ='drop') %>%spread(Tank,n)
plot1("Filter", main = data3, beh_cols = beh.cols3, palette = palette.beh3)
There have never been a filter in Jar or Small. Some fish never had a filter in their tank. Filter needs to be included in all models as a control variable.
We run a PCA in order to:
Try to reduce the number of variables to analyse
Determine which behaviours were important to explain the variability between trials
See correlations between behaviours
The PCA did not help reduce the number of variables to analyse (see Analysis_PCA.html for more explanation) so the behaviours were analysed separately with linear models. The advantage of separate linear models compared to the PCA is the possibility to quantitatively interpret the differences between tanks.
Even if we did not use PCA for further analysis, the first 4 components are plotted below, which explained 71% of variance in the data, to show the important variables and the correlations between variables.
The 1st PCA component was driven by Resting (cos2 = 0.8), Swimming (0.7) and Foraging (0.3). Swimming and Foraging opposite to Resting. This first component could be interpret as “activity”. If a fish spent a lot of time swimming and foraging during a trial, it was very little resting. This first component explained 25% of the variance in the data (as a reminder, the data is the time spent performing the different types of behaviour). So 1 quarter of the variance is a matter of activity. Keep in mind for the rest of the analyses that these behavioural types are correlated.
The 2nd PCA component was driven by Hovering (cos2 = 0.5) and Stereotypic.swimming (0.5), and a bit by Interaction with surface (0.16). Hovering and Interacting.with.Surface opposite to Stereotypic.swimming. If the fish spent a lot of time hovering (and interacting with the surface), it was very little stereotypic swimming.
The 3rd PCA component was driven mainly by Nest building (cos2 = 0.6), and a bit by Foraging (0.16), Resting (0.14) and Stereotypic Swimming (0.13). Foraging and Resting opposite to Nest building and Stereotypic Swimming. If a fish spent time foraging and resting in a trial, it was little nest building and stereotypic swimming. This makes sense, it a fish is building a nest,it is an important task and needs to be finished, so it is not scattering its time with other activities. The apparent correlation between nest building and stereotypic swimming could be due to Jar where fish in this tank rarely engaged in nest building or stereotypic swimming.
The 4th PCA component was not easily interpretable = not easily linked to the initial behavioural variables.
Sinking/Floating contributed almost nothing to the PCA (1.8%) + did not correlate strongly with any of the component. Sinking/Floating was not important to explain the variability between trials. We did not further analyse this behaviour.
The first plot is to see the trend by tank. Big red dots is for the overall mean by tank. Small black points are raw data = swimming time of each trial.
The second plot is to see the trend by fish and by tank. The dashed black line is means by tank. The other lines are the means for each fish by tank.
plot_var(data, "Swimming")
plot_var_fish(data, "Swimming")
mSwimming <-lmer(Swimming ~ Tank + Time + Filter + Order + (1|Fish), data = data)
fixed-effect model matrix is rank deficient so dropping 1 column / coefficient
# Error message due to the fact that all trials with Tank = Barren are also Order = "5"anova(mSwimming, ddf ="Kenward-Roger", type =2)
Type II Analysis of Variance Table with Kenward-Roger's method
Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
Tank 219905 54976 4 233.88 9.5912 3.376e-07 ***
Time 337219 112406 3 228.04 19.6133 2.393e-11 ***
Filter 71734 71734 1 152.69 12.5166 0.0005346 ***
Order 68083 22694 3 230.47 3.9598 0.0088524 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# estimated means of time spent swimming depending on:emmeans(mSwimming, ~ Time) # time of day
Time emmean SE df lower.CL upper.CL
7:00 AM 298 15.1 27.2 267 329
10:00 AM 240 15.1 27.2 209 271
2:00 PM 204 15.1 27.2 173 235
6:00 PM 214 15.1 27.2 183 245
Results are averaged over the levels of: Tank, Filter, Order
Degrees-of-freedom method: kenward-roger
Confidence level used: 0.95
emmeans(mSwimming, ~ Filter) # filter
Filter emmean SE df lower.CL upper.CL
No-filter 206 13.2 15.1 178 234
Filter 272 18.0 34.1 236 309
Results are averaged over the levels of: Tank, Time, Order
Degrees-of-freedom method: kenward-roger
Confidence level used: 0.95
rbind(emmeans(mSwimming, ~ Order, at =list(Tank =c("Jar", "Small", "Medium", "Large"),Order =c("1", "2", "3", "4"))),emmeans(mSwimming, ~ Order, at =list(Tank =c("Barren"),Order ="5"))) # tank order
Order emmean SE df lower.CL upper.CL
1 225 16.8 36.6 180 271
2 256 15.7 31.3 213 299
3 256 16.2 35.5 212 301
4 213 16.3 34.2 169 258
5 245 15.6 31.8 202 288
Results are averaged over some or all of the levels of: Tank, Time, Filter
Degrees-of-freedom method: kenward-roger
Confidence level used: 0.95
Conf-level adjustment: bonferroni method for 5 estimates
Effect of Tank, Time, Filter and Order!
Tank. Large swam significantly more time than Jar, Small and Medium. Fish in Large swan 92 sec [CI 46, 138] more than Jar (over a 600 sec trial), xx sec [CI xx, xx] more than Small, and xx sec [CI xx, xx] more than Medium. In addition, fish in Large swam significantly more time (xx sec [CI xx, xx]) than fish in Barren.
Time. Fish swim more in the morning than in the afternoon, especially at 7 am.
Filter. Fish swim more with a filter in their tank.
Order. All confidence intervals are overlapping so probably no significant difference between orders. It seems that fish swim more in their 2nd and 3rd tank.
Effect of Barren or tank order 5? The effect size of Tank (shown by the Sum Sq) is three times more than the effect size of Order. Max difference between orders 1-4 is 43 sec. Difference between Large and Barren/5 is 53. Effect of tank is stronger on time spent swimming, so it is likely the diff between Large and Barren/5 is due (at least party) to Tank.
# Uncomment the 2 lines below if running the script for the first time## rpt.swimming <- rpt(Swimming ~ Tank + Time + Filter + Order + (1|Fish), grname = "Fish", data = data, datatype = "Gaussian", nboot = 1000, npermut = 1000)## save(rpt.swimming, file = "Script/Repeatability rptR output/rpt.swimming")base::load("Script/Repeatability rptR output/rpt.swimming")summary(rpt.swimming)
Repeatability estimation using the lmm method
Call = rpt(formula = Swimming ~ Tank + Time + Filter + Order + (1 | Fish), grname = "Fish", data = data, datatype = "Gaussian", nboot = 1000, npermut = 1000)
Data: 252 observations
----------------------------------------
Fish (13 groups)
Repeatability estimation overview:
R SE 2.5% 97.5% P_permut LRT_P
0.217 0.0801 0.0632 0.376 0.001 0
Bootstrapping and Permutation test:
N Mean Median 2.5% 97.5%
boot 1000 0.20992 0.207 0.0632 0.3762
permut 1000 0.00876 0.000 0.0000 0.0491
Likelihood ratio test:
logLik full model = -1453.809
logLik red. model = -1470.599
D = 33.6, df = 1, P = 3.42e-09
----------------------------------------
Likelihood ratio test indicates a statistically significant random effect. Meaning that fish behaved differently among each others in terms of swimming. But the repeatability is quite low (0.2 [95% CI 0.06, 0.37]).
Time emmean SE df lower.CL upper.CL
7:00 AM 146 29.9 18.5 82.9 208
10:00 AM 203 29.9 18.5 140.7 266
2:00 PM 263 29.9 18.5 200.9 326
6:00 PM 291 29.9 18.5 228.5 354
Results are averaged over the levels of: Tank, Filter, Order
Degrees-of-freedom method: kenward-roger
Confidence level used: 0.95
rbind(emmeans(mResting, ~ Order, at =list(Tank =c("Jar", "Small", "Medium", "Large"),Order =c("1", "2", "3", "4"))),emmeans(mResting, ~ Order, at =list(Tank =c("Barren"),Order ="5")))
Order emmean SE df lower.CL upper.CL
1 251 31.8 23.1 162.2 341
2 204 30.4 20.0 117.8 291
3 215 31.1 21.7 127.4 303
4 290 31.2 21.7 202.2 378
5 168 30.3 19.9 81.9 255
Results are averaged over some or all of the levels of: Tank, Time, Filter
Degrees-of-freedom method: kenward-roger
Confidence level used: 0.95
Conf-level adjustment: bonferroni method for 5 estimates
Effect of Tank, Time and Order.
Tank. Large rested significantly less time than Jar and Medium (almost significant for Small). Fish in Large rested 109 sec [CI 40, 178] less time than fish in Jar (over a 600 sec trial), and xx sec [CI xx, xx] more fish in Medium. This is in line with the PCA and the results of Swimming: Fish that spent time swimming spent less time resting. Fish in Large were overall more active. No significant difference between Large and Barren.
Time. Fish rest less time in the morning, especially at 7 am. In line with the PCA and the results of Swimming.
Order. All confidence intervals are overlapping so probably no significant difference between orders. It seems that fish rest more in their 1st and 4th tank.
# Uncomment the 2 lines below if running the script for the first time## rpt.resting <- rpt(Resting ~ Tank + Time + Filter + Order + (1|Fish), grname = "Fish", data = data, datatype = "Gaussian", nboot = 1000, npermut = 1000)## save(rpt.resting, file = "Script/Repeatability rptR output/rpt.resting")base::load("Script/Repeatability rptR output/rpt.resting")summary(rpt.resting)
Repeatability estimation using the lmm method
Call = rpt(formula = Resting ~ Tank + Time + Filter + Order + (1 | Fish), grname = "Fish", data = data, datatype = "Gaussian", nboot = 1000, npermut = 1000)
Data: 252 observations
----------------------------------------
Fish (13 groups)
Repeatability estimation overview:
R SE 2.5% 97.5% P_permut LRT_P
0.406 0.109 0.162 0.582 0.001 0
Bootstrapping and Permutation test:
N Mean Median 2.5% 97.5%
boot 1000 0.39057 0.392 0.162 0.5820
permut 1000 0.00925 0.000 0.000 0.0532
Likelihood ratio test:
logLik full model = -1556.775
logLik red. model = -1595.284
D = 77, df = 1, P = 8.48e-19
----------------------------------------
Likelihood ratio test indicates a statistically significant random effect. Meaning that fish behaved differently among each others in terms of swimming. The repeatability is good 0.4 [95% CI 0.16, 0.58].
lm_diagnosis(mResting)
[1] "check constant variance over fitted values"
[1] "Normality of Resting"
[1] "Normality random residuals"
The model seems good.
Just a plot with the amount of time resting at the different places depending on the tank. Each bar value is the mean of resting times over trials and fish.
Analysis only for Small, Medium and Large.
From the graphs, we can see that fish use different places to rest, not only one type. They use all the different places available. It does not seem that there is a preferred resting place.
Interesting, fish avoided resting on filter. 48 trials with a filter in the tank (24 in Medium + 24 in Large) but only one trial were the fish rested on the filter for Medium and Large. Fish only rested on filter in Barren.
# Number of trials with a filtertable(data$Tank, data$Filter)
No-filter Filter
Jar 48 0
Small 52 0
Medium 28 24
Large 28 24
Barren 24 24
# Trials with resting on filterfilter(master[,c(1:5,7:8)], Resting.place =="Filter")
The data are clearly not following a normal distribution. It seems that a beta distribution could suit but foraging is not a continuous variable ranging from 0 to 1. Foraging has thus been analysed as a binary variable: 1 if fish spent time foraging during this trial, 0 otherwise.
There were 168 trials (out of 252) during which no foraging happened.
The plots are in percentage of trials during which the fish foraged over the total number of trials.
plot_var_binary(data, "Foraging.bin")
plot_var_binary_fish(data, "Foraging.bin")
mForaging <-glmmTMB(Foraging.bin ~ Tank + Time + Filter + Order + (1|Fish), data = data, family =binomial)
dropping columns from rank-deficient conditional model: Order5
glmmTMB:::Anova.glmmTMB(mForaging)
Analysis of Deviance Table (Type II Wald chisquare tests)
Response: Foraging.bin
Chisq Df Pr(>Chisq)
Tank 31.4734 4 2.451e-06 ***
Time 1.8543 3 0.6032
Filter 0.4113 1 0.5213
Order 4.5561 3 0.2073
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# example of differences between Jar and Large## Contrast estimate1/0.09
[1] 11.11111
## Upper CI1/0.015
[1] 66.66667
## Lower CI1/0.493
[1] 2.028398
Effect of Tank.
As a reminder, an odds.ratio < 1 between tank X vs tank Y means the probability of foraging during a trial in tank X is smaller that the probability of foraging during a trial in tank Y. An odd ratio for instance of 0.2 means that a fish is (1 / 0.2) = five times more likely to forage during a trial in tank Y than in Tank X. If we imagine 5 trials, fish will forage on average during 1 trial out of 5 in Tank X whereas fish will forage on average during 5 trials out of 5 in Tank Y.
Tank. Fish were more likely to forage during a trial in Large compared to Jar, Small and Medium. Again in accordance with the PCA and the results of Swimming and Resting. Fish in Large were on average 11 times [CI 2, 67] more likely to forage during a trial than fish in Jar, xx times [CI xx, xx] than fish in Small, and xx times [CI xx, xx] than fish in Medium. In addition, fish were xx times [CI xx, xx] more likely to forage during a trial in Large than Barren. In accordance with the PCA and the results of Swimming. This time, there was also a significant difference between small and medium.
rpt.foraging <-rpt(Foraging.bin ~ Tank + Time + Filter + Order + (1|Fish), grname ="Fish", data = data, datatype ="Binary", nboot =0, npermut =0)
fixed-effect model matrix is rank deficient so dropping 1 column / coefficient
fixed-effect model matrix is rank deficient so dropping 1 column / coefficient
# can calculate repeatability but not the CI. I tried using bootstrap and permutation.# Likelihood ratio test of random effectmForaging0 <-glmmTMB(Foraging.bin ~ Tank + Time + Filter + Order, data = data, family =binomial)
dropping columns from rank-deficient conditional model: Order5
Can calculate the repeatability but not its CI. Cannot calculate repeatability for Stereotypic swimming anyway. Hard to estimate repeatability on binary data. I don’t know how to do it without the package rptR. I think we don’t have enough data power anyway to calculate repeatability with a binary variable.
Likelihood ratio test indicates a statistically significant random effect. Meaning that fish behaved differently among each others in terms of foraging.
Tank. Jar were less likely to perform stereotypic swimming during a trial than Small/Medium/Large but only significant between Jar and Small. Fish in Small were xx times [CI xx, xx] more likely to perform stereotypic swimming during a trial than fish in Jar. Almost significant difference between Large and Barren: Fish in Barren were 3.4 times [CI xx, xx] more likely to perform stereotypic swimming during a trial than fish in Large.
# Attempt to calculate repeatabilityrpt.SS <-rpt(SS.bin ~ Tank + Time + Filter + Order + (1|Fish), grname ="Fish", data = data, datatype ="Binary", nboot =0, npermut =0)
fixed-effect model matrix is rank deficient so dropping 1 column / coefficient
Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl = control$checkConv, :
Model failed to converge with max|grad| = 0.00851543 (tol = 0.002, component 1)
fixed-effect model matrix is rank deficient so dropping 1 column / coefficient
Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl = control$checkConv, :
Model failed to converge with max|grad| = 0.00851543 (tol = 0.002, component 1)
# error# Likelihood ratio test of random effectmSS0 <-glmmTMB(SS.bin ~ Tank + Time + Filter, data = data, family =binomial)anova(mSS0, mSS)
Data: data
Models:
mSS0: SS.bin ~ Tank + Time + Filter, zi=~0, disp=~1
mSS: SS.bin ~ Tank + Time + Filter + Order + (1 | Fish), zi=~0, disp=~1
Df AIC BIC logLik deviance Chisq Chi Df Pr(>Chisq)
mSS0 9 277.42 309.19 -129.710 259.42
mSS 13 208.92 254.81 -91.462 182.92 76.496 4 9.614e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Error when calculating the repeatability with rptR.
Likelihood ratio test indicates a statistically significant random effect. Meaning that fish behaved differently among each others in terms of stereotypic swimming.
mSS_res <-simulateResiduals(mSS)plot(mSS_res)
plotResiduals(mSS_res, form = data$Tank)
plotResiduals(mSS_res, form = data$Time)
plotResiduals(mSS_res, form = data$Filter)
# Problem with Filter, I retried the model without FiltermSS2 <-glmmTMB(SS.bin ~ Tank + Time + (1|Fish), data = data, family =binomial)plot(simulateResiduals(mSS2))
It is expected to have a problem with filter as there are more than twice more trials without filter than with filter. No problem when removing Filter from the model. The model seems good.
Just a plot with the type of stereotypic swimming depending on the tank. To stick with the analysis, it is a count (count = 1 if the fish performs a certain type of stereotypic swimming during a trial).
It seems that there are not differences between tanks. Just circles seem specific to larger tanks (Medium/Large/Barren).
Tank Fish Time Stereotypic.swimming.type Nb.rep
1 Small Dragon 7:00 AM Pacing 328
2 Small Dragon 10:00 AM Pacing 76
3 Small Dragon 2:00 PM Pacing 20
4 Small Dragon 6:00 PM Pacing 8
5 Small Dragon 6:00 PM Pacing front wall 8
6 Barren Dragon 7:00 AM Pacing 4
7 Barren Dragon 10:00 AM Pacing 5
8 Barren Dragon 2:00 PM Pacing 19
9 Barren Dragon 6:00 PM Pacing 4
10 Jar Elf 7:00 AM Zig zag 4
11 Jar Elf 6:00 PM Zig zag 6
12 Small Elf 7:00 AM Pacing 15
13 Small Elf 10:00 AM Pacing 15
14 Small Elf 2:00 PM Pacing 109
15 Small Elf 6:00 PM Pacing 25
16 Medium Elf 7:00 AM Pacing 4
17 Medium Elf 10:00 AM Pacing 34
18 Medium Elf 2:00 PM Pacing 14
19 Large Elf 10:00 AM Circles 12
20 Large Elf 10:00 AM Pacing 8
21 Barren Elf 7:00 AM Pacing 186
22 Barren Elf 10:00 AM Pacing 8
23 Barren Elf 6:00 PM Pacing 8
24 Small Fairy 7:00 AM Pacing 234
25 Small Fairy 10:00 AM Pacing 340
26 Small Fairy 2:00 PM Pacing 381
27 Small Fairy 6:00 PM Pacing 212
28 Large Fairy 10:00 AM Circles 8
29 Large Fairy 10:00 AM Pacing 22
30 Large Fairy 2:00 PM Pacing 7
31 Barren Fairy 7:00 AM Pacing 6
32 Barren Fairy 10:00 AM Pacing 396
33 Barren Fairy 2:00 PM Pacing 132
34 Barren Fairy 6:00 PM Pacing 111
35 Small Ghost 7:00 AM Pacing 3
36 Small Kraken 7:00 AM Pacing 6
37 Small Kraken 7:00 AM Pacing with a hover 790
38 Small Kraken 10:00 AM Pacing with a hover 1204
39 Small Kraken 10:00 AM Zig zag 77
40 Small Kraken 2:00 PM Pacing with a hover 746
41 Small Kraken 2:00 PM Zig zag 64
42 Medium Kraken 10:00 AM Circles 13
43 Medium Kraken 2:00 PM Circles 22
44 Large Kraken 7:00 AM Circles 9
45 Large Kraken 10:00 AM Pacing 77
46 Large Kraken 2:00 PM Circles 43
47 Large Kraken 2:00 PM Pacing 41
48 Large Kraken 6:00 PM Circles 6
49 Barren Kraken 7:00 AM Circles 15
50 Barren Kraken 7:00 AM Zig zag 11
51 Barren Kraken 10:00 AM Circles 41
52 Barren Kraken 10:00 AM Pacing 28
53 Barren Kraken 2:00 PM Pacing 21
54 Barren Kraken 2:00 PM Zig zag 12
55 Barren Kraken 6:00 PM Circles 7
56 Barren Kraken 6:00 PM Pacing 0
57 Small Orange Pendek 10:00 AM Pacing 5
58 Medium Orange Pendek 7:00 AM Pacing 8
59 Medium Orange Pendek 10:00 AM Pacing 41
60 Medium Orange Pendek 2:00 PM Pacing 4
61 Medium Orange Pendek 6:00 PM Pacing 3
62 Large Orange Pendek 7:00 AM Circles 15
63 Jar Phoenix 10:00 AM Pacing 3
64 Small Phoenix 7:00 AM Pacing 7
65 Small Phoenix 2:00 PM Pacing 14
66 Small Phoenix 6:00 PM Pacing 8
67 Medium Phoenix 7:00 AM Pacing 36
68 Medium Phoenix 10:00 AM Pacing 19
69 Medium Phoenix 2:00 PM Pacing 100
70 Medium Phoenix 6:00 PM Pacing 58
71 Large Phoenix 7:00 AM Pacing 6
72 Large Phoenix 10:00 AM Pacing 19
73 Large Phoenix 2:00 PM Pacing 13
74 Large Phoenix 6:00 PM Pacing 8
75 Barren Phoenix 10:00 AM Circles 27
76 Barren Phoenix 10:00 AM Pacing 18
77 Barren Phoenix 2:00 PM Pace then hover 0
78 Barren Phoenix 6:00 PM Circles 3
79 Barren Phoenix 6:00 PM Pace then hover 0
80 Jar Wizard 2:00 PM Pacing 7
81 Small Wizard 7:00 AM Pacing 681
82 Small Wizard 10:00 AM Pacing 8
83 Small Wizard 6:00 PM Pacing 52
84 Medium Wizard 7:00 AM Pacing 35
85 Medium Wizard 10:00 AM Pacing 16
86 Large Wizard 7:00 AM Pacing 35
87 Large Wizard 10:00 AM Pacing 409
88 Large Wizard 2:00 PM Pacing 277
89 Large Wizard 6:00 PM Pacing 185
90 Barren Wizard 7:00 AM Pacing 527
91 Barren Wizard 10:00 AM Pacing 472
92 Barren Wizard 2:00 PM Pacing 432
93 Barren Wizard 6:00 PM Pacing 641
I don’t think there are enough data to really say something about the number of repetitions. The number of repetitions seems pretty unique to a fish in a certain tank. I don’t see an obvious pattern depending on the tank. The interesting thing is that the stereotypic swimming seemed consistent in a tank for a fish (most or all trials of that day with stereotypic swimming). It is a pitty we couldn’t calculate the repeatability of the binomial glm of Stereotypic Swimming because it would have been interesting.
Tank. Fish were more likely to interact with the surface during a trial in Jar/Medium compared to Large (not significant for Small). Fish in Jar were x times [CI xx, xx] more likely to interact with the surface during a trial than fish in Large, and Fish in Medium were x times [CI xx, xx] then fish in Large. In addition, fish were xx times [CI xx, xx] more likely to interact with a surface during a trial in Barren than in Large.
mInteracting0 <-glmmTMB(Interacting.bin ~ Tank + Time + Filter + Order, data = data, family =binomial)
dropping columns from rank-deficient conditional model: Order5
Likelihood ratio test indicates a statistically significant random effect. Meaning that fish behaved differently among each others in terms of interaction with surface.
Just a plot with the type of interaction depending on the tank. To stick with the analysis, it is a count (count = 1 if the fish performs a certain type of interaction with surface during a trial).
The second plot groups similar interactions with surface together.
Filter prob SE df asymp.LCL asymp.UCL
No-filter 0.2125 0.0665 Inf 0.11018 0.3702
Filter 0.0166 0.0133 Inf 0.00338 0.0771
Results are averaged over the levels of: Tank, Time, Order
Confidence level used: 0.95
Intervals are back-transformed from the logit scale
Effect of Filter only.
Tank. Almost significant.
Filter. Fish were more likely to build a nest without a filter in their tank.
mNest0 <-glmmTMB(Nest.bin ~ Tank + Time + Filter + Order, data = data, family =binomial)
dropping columns from rank-deficient conditional model: Order5
Likelihood ratio test indicates a statistically significant random effect. Meaning that fish behaved differently among each others in terms of nest building.
To analyse the amount of time the fish was hovering on the 204 trials with hovering time > 0, we tried different models described in “Analysis_Hovering”. The best model was a linear mixed model on the amount of time spent hovering with weighted least squares (WLS). We had to use WLS because the error variance was increasing with the fitted values-higher error variance associated with high hovering time values. It was not possible to use WLS with the lmer package so we had to use the nlme package. The nlme package does not handle confounding levels of two factors - the fact that Tank = Barren is the same as Order = 5. So we had to remove Order from the analysis. The addition of Order was not changing the analysis outcomes in the other models.
hist1(data$Hovering[data$Hovering!=0]) # histogram without the zeros
Even if there are less zeros than Foraging or Stereotypic Swimming, it is not a normal distribution. There were only 48 trials (out of 252) during which no hovering happened. So 204 trials where we could study the amount of time hovering in 204 trials.
We fitted a glm distribution like Foraging and Stereotypic Swimming on the probability to hover (dependent variable is 1 if hovering occurred during the trial, zero otherwise).
# Effect of tank of the probability to hover during a trialplot_var_binary(data, "Hovering.bin")
plot_var_binary_fish(data, "Hovering.bin")
# Among the trials where the fish hovers, effect of tank on the amount of time hoveringdata %>%filter(Hovering >0) %>%plot_var(., "Hovering")
data %>%filter(Hovering >0) %>%plot_var_fish(., "Hovering")
Both the probability to hover and the time spent hovering seems to be higher in Jar compared to the others. All fish besides Goblin hovered more in Jar compared to Small.
Y variable = probability to hover during a trial
mHovering <-glmmTMB(Hovering.bin ~ Tank + Time + Filter + Order + (1|Fish), data = data, family =binomial)
dropping columns from rank-deficient conditional model: Order5
glmmTMB:::Anova.glmmTMB(mHovering)
Analysis of Deviance Table (Type II Wald chisquare tests)
Response: Hovering.bin
Chisq Df Pr(>Chisq)
Tank 6.6046 4 0.15832
Time 9.4413 3 0.02396 *
Filter 4.9879 1 0.02553 *
Order 1.9380 3 0.58538
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
emmeans(mHovering, ~ Time, type ="response")
Time prob SE df asymp.LCL asymp.UCL
7:00 AM 0.918 0.0400 Inf 0.798 0.969
10:00 AM 0.870 0.0531 Inf 0.727 0.944
2:00 PM 0.727 0.0803 Inf 0.546 0.855
6:00 PM 0.746 0.0776 Inf 0.568 0.867
Results are averaged over the levels of: Tank, Filter, Order
Confidence level used: 0.95
Intervals are back-transformed from the logit scale
emmeans(mHovering, ~ Filter, type ="response")
Filter prob SE df asymp.LCL asymp.UCL
No-filter 0.907 0.0338 Inf 0.816 0.955
Filter 0.712 0.1001 Inf 0.487 0.866
Results are averaged over the levels of: Tank, Time, Order
Confidence level used: 0.95
Intervals are back-transformed from the logit scale
No effect of Tank on the probability to hover during a trial, only an effect of Time and Filter
Time. Fish were more likely to hover in the morning.
Filter. Fish were less likely to hover with a filter in their tank.
Y variable = amount of time spent hovering during a trial. Only trials with hovering time > 0
mHovering2 <-lme(Hovering ~ Tank + Time + Filter, random =~1| Fish, data = data[data$Hovering>0, ], weights =varPower(), control =lmeControl(maxIter =20000))anova(mHovering2)
Time emmean SE df lower.CL upper.CL
7:00 AM 39.3 5.06 12 28.2 50.3
10:00 AM 48.3 5.72 12 35.8 60.8
2:00 PM 48.1 5.68 12 35.7 60.4
6:00 PM 42.4 5.23 12 31.0 53.8
Results are averaged over the levels of: Tank, Filter
Degrees-of-freedom method: containment
Confidence level used: 0.95
emmeans(mHovering2, ~ Filter)
Filter emmean SE df lower.CL upper.CL
No-filter 52.2 5.30 12 40.7 63.8
Filter 36.8 6.53 12 22.5 51.0
Results are averaged over the levels of: Tank, Time
Degrees-of-freedom method: containment
Confidence level used: 0.95
Effect of Tank, Time and Filter.
Tank. Jar hovered significantly more time than Small, Medium and Large. Fish in Jar hovered 53 sec [CI 20, 85] more than Small (over a 600 sec trial), 53 sec [CI 20, 86] more than Medium, and 61 sec [CI 28, 93] more than Large. Fish in medium hovered more time than fish in Large. In addition, fish in Barren hovered significantly more time (22 sec [CI 12, 35]) than fish in Large.
Time. Fish hovered more time in the middle of the day.
Filter. Fish hovered less time with a filter in their tank.
It seems that the tank has an influence on whether fish prefer being on the upper half or lower half of the tank.
We can do different models: + Look at the percentage of time spent up of the trial. Fit a beta distribution. Problem: All percentages need to be 0 < perc < 100%. There are trials with 100% so we can’t use beta distribution.
Look at the count of seconds (how many seconds the fish spend up of the tank). Fit a binomial distribution. Problem: The diagnostics plots were very bad when fitting mUp <- glmmTMB(cbind(up, down) ~ Tank + Time + Filter + (1|Fish), data = dataUpDown, family = binomial)
Look simply at the actual time spent up. Fit a normal distribution. The response variable can be adjusted by the fact that the trial were not perfectly 600 sec. \(adj.up= \frac{\text{time spent up} * 600}{\text{trial total duration}}\). It is what has been done.
mUp <-lmer(adj.up ~ Tank + Time + Filter + Order + (1|Fish), data = dataUpDown)
fixed-effect model matrix is rank deficient so dropping 1 column / coefficient
anova(mUp, ddf ="Kenward-Roger", type =2)
Type II Analysis of Variance Table with Kenward-Roger's method
Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
Tank 251386 62846 4 234.07 3.8215 0.0049776 **
Time 284189 94730 3 228.06 5.7613 0.0008159 ***
Filter 87414 87414 1 130.01 5.3164 0.0227095 *
Order 70637 23546 3 230.78 1.4320 0.2341679
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
emmeans(mUp, ~ Time) # estimated means of time spent swimming depending on the time of the day
Time emmean SE df lower.CL upper.CL
7:00 AM 274 24.1 30.6 225 323
10:00 AM 279 24.1 30.6 230 329
2:00 PM 224 24.1 30.6 175 273
6:00 PM 200 24.1 30.6 151 249
Results are averaged over the levels of: Tank, Filter, Order
Degrees-of-freedom method: kenward-roger
Confidence level used: 0.95
emmeans(mUp, ~ Filter) # estimated means of time spent swimming depending on the time of the day
Filter emmean SE df lower.CL upper.CL
No-filter 280 20.6 15.4 237 324
Filter 208 28.9 35.1 150 267
Results are averaged over the levels of: Tank, Time, Order
Degrees-of-freedom method: kenward-roger
Confidence level used: 0.95
Effect of Tank, Time and Filter.
Tank. Statistically significant difference between Small and Medium/Jar: Fish in Small tank spent on average 103 more seconds [95% CI 26, 181] on the upper half of the tank compared to fish in Medium tanks. At the opposite, Fish in Small tank spent on average 71 more seconds [95% CI 26, 181] on the lower half of the tank compared to fish in Jar tanks.
Time. Fish spent more time on the upper half of the tank in the morning.
Filter. Fish spent more time on the upper half of the tank with a filter in their tank.